import pexpect
import sys
import os
import logging


def ssh_login(hostname, username, password):
    #ssh_cmd = "ssh -l {} -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null {}"
    #-o StrictHostKeyChecking=no 自动接收新的公钥
    #-o UserKnownHostsFile=/dev/null 禁用 SSH 远程主机的公钥检查，避免公钥改变中断警告，变成了首次连接提示
#使用 pexpect.spawn 方法来创建一个 ssh 子进程
    logging.info("【信息】正在登入IP_{}设备中".format(hostname))
    global child
    child= pexpect.spawn("ssh -l {} -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null {}".format(username,hostname))
#使用 expect 方法匹配返回结果中的字符串。这里匹配的内容是一个数组，其内容可以是正则表达式。返回 #值为所匹配的字符在数组中的编号
    i = child.expect([pexpect.TIMEOUT, "assword:" ])
    if i ==0:
        logging.error("【灾难】IP_{}设备登入失败，正在跳过".format(hostname))
#如果匹配的是“password:”， expect返回的结果为 1
    elif i == 1:
#使用 sendline 方法，向设备发送密码字符串
        child.sendline(password)
        if child.expect([pexpect.TIMEOUT,">|#"]) == 1:
            return child
            logging.info("【完美】IP_{}设备登入成功".format(hostname))
        else :
            logging.error("【灾难】IP_{}设备密码校验失败，正在跳过".format(hostname))
            sys.exit(1)
            pass


#定义一个向设备发送命令的函数。 这个函数可以被多次使用 def show cmd(child, cmd, host str):
def show_cmd(child,cmd,host_str,ip,time_log):
    child.sendline (cmd)
    logging.debug("【信息】发送命令{}".format(cmd))
    i = child.expect([pexpect.TIMEOUT, host_str])
    if i == 0 :
        logging.warning("【严重】未检测到命令{}输出，输出信息为{}\n{}".format(cmd,child.before,child.after,))
    elif i ==1 :
        log(host_str,child.before,ip,time_log)
        logging.debug("【完美】正常检测到命令{}输出".format(cmd))

def cmd_screen_length_0(length0):
    child.sendline("{}".format(length0))
    logging.debug("【信息】发送关闭分屏显示功能，命令{}".format(length0))
    i = child.expect([pexpect.TIMEOUT, "\<.*>|\n.*#"])
    if i == 0:
        logging.warning("【严重】检测到命令回显未正常输出，输出信息为{}\n{}".format(length0,child.before,child.after,))
    elif i == 1:
        logging.debug("【完美】正常回显，返回设备名称值{}".format(child.after))
        return child.after

def main(ip,username,password,manu_f,time_log):
    logfile_time_log(time_log)
    child = ssh_login(ip, username, password)
    with open('manufacturers/{}.os'.format(manu_f), 'r', encoding='utf-8') as command:
        cmd_all_undo = command.readlines()
        cmd_all = [x.strip() for x in cmd_all_undo if x.strip()]
        logging.debug("【信息】待输入的命令为".format(" ".join(cmd_all)))
        host_str = cmd_screen_length_0(cmd_all[0])
        for cmd in cmd_all[1:]:
            logging.debug("【信息】正在输入命令{}".format(cmd))
            show_cmd(child, cmd, host_str, ip, time_log)
    logging.info("【完美】IP_{}设备退出登陆".format(ip))
    sys.exit(1)


def log(host_str,result,ip,time_log):
    host_str_done=bytes.decode(host_str).replace("<", "").replace(">", "").replace("#", "").replace("\n","")
    log_name=host_str_done+"&"+ ip+".log"
    logend = os.getcwd() + '/log/' + time_log + '/'+log_name
    logging.debug("【信息】设备{}_IP{}_写入日志文件{}中".format(host_str_done,ip,time_log + '/'+log_name))
    with open(logend, 'a+') as ssh_result:
        ssh_result.write(bytes.decode(result,encoding='gb18030'))
        #print(result)
        logging.debug("【信息】设备{}_IP{}_写入日志文件{}完成".format(host_str_done, ip, time_log + '/'+log_name))


def logfile_time_log(time_log):
    a = os.path.exists('log')
    if a == False:
        logging.warning("【警告】检测到log文件夹不存在，正在创建")
        logging.debug("【信息】当前目录为{}".format(os.getcwd()))
        os.mkdir(os.getcwd() + '/log')
        logging.warning("【信息】log文件夹已创建")
    b = os.path.exists('log/'+time_log)
    if b == False:
        logging.warning("【警告】检测到当天日志文件夹不存在，正在创建")
        os.mkdir(os.getcwd() + '/log/' + time_log)
        logging.warning("【信息】log文件夹已创建")